package model

import (
	"context"
	"fmt"
	"strings"

	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ SysFileModel = (*customSysFileModel)(nil)

type (
	// SysFileModel is an interface to be customized, add more methods here,
	// and implement the added methods in customSysFileModel.
	SysFileModel interface {
		sysFileModel
		withSession(session sqlx.Session) SysFileModel
		FindUserPage(ctx context.Context, offset int, size int, userId int64, fileTypeList []string, parentId int64) ([]SysFile, error)
		FindUserCount(ctx context.Context, userId int64, fileTypeList []string, parentId int64) (int, error)
		FindByName(ctx context.Context, userId int64, name string) (file *SysFile, err error)
		FindByFileName(ctx context.Context, userId int64, name string) ([]SysFile, error)
	}

	customSysFileModel struct {
		*defaultSysFileModel
	}
)

func (m *customSysFileModel) FindByFileName(ctx context.Context, userId int64, name string) ([]SysFile, error) {
	query := fmt.Sprintf("select %s from %s where  userId = ? and name like ?", sysFileRows, m.table)
	var files []SysFile
	err := m.conn.QueryRowsCtx(ctx, &files, query, userId, "%"+name+"%")
	if err != nil {
		return nil, err
	}
	return files, nil
}

func (m *customSysFileModel) FindByName(ctx context.Context, userId int64, name string) (file *SysFile, err error) {
	query := fmt.Sprintf("select %s from %s where userId = ? and name = ?", sysFileRows, m.table)
	var resp SysFile
	err = m.conn.QueryRowCtx(ctx, &resp, query, userId, name)
	if err != nil {
		return nil, err
	}
	return &resp, nil

}

func (m *customSysFileModel) FindUserCount(ctx context.Context, id int64, fileTypeList []string, parentId int64) (int, error) {
	var args []interface{}
	query := fmt.Sprintf("select count(*) from %s where userId = ?", m.table)
	args = append(args, id)
	if len(fileTypeList) > 0 {
		query += " and extendName in (" + strings.Repeat("?,", len(fileTypeList)-1) + "?)"
		for _, fileType := range fileTypeList {
			args = append(args, fileType)
		}
	}
	if parentId > 0 {
		query += " and parentId = ?"
		args = append(args, parentId)
	}
	var count int
	err := m.conn.QueryRowCtx(ctx, &count, query, args...)
	if err != nil {
		return 0, err
	}
	return count, err

}

func (m *customSysFileModel) FindUserPage(ctx context.Context, offset int, size int, userId int64, fileTypeList []string, parentId int64) ([]SysFile, error) {
	query := fmt.Sprintf("select %s from %s where userId = ? ", sysFileRows, m.table)
	var args []interface{}
	args = append(args, userId)
	if len(fileTypeList) > 0 {
		query += " and extendName in (" + strings.Repeat("?,", len(fileTypeList)-1) + "?)"
		for _, fileType := range fileTypeList {
			args = append(args, fileType)
		}
	}
	if parentId > 0 {
		query += " and parentId = ?"
		args = append(args, parentId)
	} else {
		query += " and parentId = 0"
	}
	query += " order by updateTime desc limit ?,?"
	args = append(args, offset, size)

	var files []SysFile
	err := m.conn.QueryRowsCtx(ctx, &files, query, args...)
	if err != nil {
		return nil, err
	}
	return files, nil
}

// NewSysFileModel returns a model for the database table.
func NewSysFileModel(conn sqlx.SqlConn) SysFileModel {
	return &customSysFileModel{
		defaultSysFileModel: newSysFileModel(conn),
	}
}

func (m *customSysFileModel) withSession(session sqlx.Session) SysFileModel {
	return NewSysFileModel(sqlx.NewSqlConnFromSession(session))
}
